import { defineStore } from 'pinia'
import { ElMessage } from 'element-plus'
import { mockLogin, mockGetUserMenus, mockGetUserInfo } from '../api/auth'
import router from '../routers/router'

export const useAuthStore = defineStore('auth', {
  state: () => ({
    // 用户信息
    userInfo: {
      id: null,
      username: '',
      name: '',
      role: '',
      avatar: '',
      email: '',
      phone: ''
    },
    // JWT Token
    token: localStorage.getItem('token') || '',
    // 用户权限列表
    permissions: JSON.parse(localStorage.getItem('permissions') || '[]'),
    // 动态菜单
    menus: JSON.parse(localStorage.getItem('menus') || '[]'),
    // 动态路由
    dynamicRoutes: [],
    // 登录状态
    isLoggedIn: !!localStorage.getItem('token'),
    // 菜单加载状态
    menusLoaded: false
  }),
  
  getters: {
    // 获取用户名
    userName: (state) => state.userInfo.name || state.userInfo.username,
    
    // 获取用户角色
    userRole: (state) => state.userInfo.role,
    
    // 获取用户头像
    userAvatar: (state) => state.userInfo.avatar,
    
    // 检查是否已登录
    isAuthenticated: (state) => state.isLoggedIn && !!state.token,
    
    // 获取菜单树
    menuTree: (state) => state.menus,
    
    // 获取扁平化菜单列表
    flatMenus: (state) => {
      const flatten = (menus, result = []) => {
        menus.forEach(menu => {
          result.push(menu)
          if (menu.children && menu.children.length > 0) {
            flatten(menu.children, result)
          }
        })
        return result
      }
      return flatten(state.menus)
    }
  },
  
  actions: {
    /**
     * 用户登录
     */
    async login(loginData) {
      try {
        const response = await mockLogin(loginData)
        const { token, userInfo, permissions } = response.data
        
        // 存储用户信息
        this.userInfo = userInfo
        this.token = token
        this.permissions = permissions
        this.isLoggedIn = true
        
        // 持久化存储
        localStorage.setItem('token', token)
        localStorage.setItem('userInfo', JSON.stringify(userInfo))
        localStorage.setItem('permissions', JSON.stringify(permissions))
        
        // 获取用户菜单
        await this.loadUserMenus()
        
        return response
      } catch (error) {
        this.logout()
        throw error
      }
    },
    
    /**
     * 加载用户菜单
     */
    async loadUserMenus() {
      try {
        const response = await mockGetUserMenus(this.userInfo.role)
        const menus = response.data
        
        // 过滤有权限的菜单
        const filteredMenus = this.filterMenusByPermissions(menus)
        
        this.menus = filteredMenus
        this.menusLoaded = true
        
        // 持久化存储
        localStorage.setItem('menus', JSON.stringify(filteredMenus))
        
        // 生成动态路由
        this.generateDynamicRoutes(filteredMenus)
        
        return filteredMenus
      } catch (error) {
        console.error('加载菜单失败:', error)
        ElMessage.error('加载菜单失败')
        throw error
      }
    },
    
    /**
     * 根据权限过滤菜单
     */
    filterMenusByPermissions(menus) {
      return menus.filter(menu => {
        // 如果用户有通配符权限，显示所有菜单
        if (this.permissions.includes('*')) {
          if (menu.children) {
            menu.children = this.filterMenusByPermissions(menu.children)
          }
          return true
        }
        
        // 检查菜单权限
        if (menu.meta && menu.meta.permissions && menu.meta.permissions.length > 0) {
          const hasPermission = menu.meta.permissions.some(permission => 
            this.permissions.includes(permission)
          )
          if (!hasPermission) {
            return false
          }
        }
        
        // 递归处理子菜单
        if (menu.children && menu.children.length > 0) {
          menu.children = this.filterMenusByPermissions(menu.children)
          // 如果所有子菜单都没有权限，则隐藏父菜单
          return menu.children.length > 0
        }
        
        return true
      })
    },
    
    /**
     * 生成动态路由
     */
    generateDynamicRoutes(menus) {
      const routes = []
      
      const generateRoute = (menu) => {
        // 只有有component的菜单才生成路由
        if (menu.component) {
          const route = {
            path: menu.path,
            name: menu.name,
            component: () => import(`../views/${menu.component}.vue`).catch(() => {
              // 如果组件不存在，返回404页面
              return import('../views/404.vue')
            }),
            meta: {
              ...menu.meta,
              title: menu.title,
              icon: menu.icon
            }
          }
          routes.push(route)
        }
        
        // 递归处理子菜单
        if (menu.children && menu.children.length > 0) {
          menu.children.forEach(child => generateRoute(child))
        }
      }
      
      menus.forEach(menu => generateRoute(menu))
      
      this.dynamicRoutes = routes
      
      // 将动态路由添加到路由表
      routes.forEach(route => {
        if (!router.hasRoute(route.name)) {
          // 添加到Layout的子路由中
          router.addRoute('Layout', route)
        }
      })
    },
    
    /**
     * 验证token有效性
     */
    async validateToken() {
      if (!this.token) {
        return false
      }
      
      try {
        const response = await mockGetUserInfo(this.token)
        const userInfo = response.data
        
        // 更新用户信息
        this.userInfo = userInfo
        this.permissions = userInfo.permissions
        this.isLoggedIn = true
        
        // 如果菜单未加载，则加载菜单
        if (!this.menusLoaded) {
          await this.loadUserMenus()
        }
        
        return true
      } catch (error) {
        console.error('Token验证失败:', error)
        this.logout()
        return false
      }
    },
    
    /**
     * 用户登出
     */
    logout() {
      // 清除状态
      this.userInfo = {
        id: null,
        username: '',
        name: '',
        role: '',
        avatar: '',
        email: '',
        phone: ''
      }
      this.token = ''
      this.permissions = []
      this.menus = []
      this.dynamicRoutes = []
      this.isLoggedIn = false
      this.menusLoaded = false
      
      // 清除本地存储
      localStorage.removeItem('token')
      localStorage.removeItem('userInfo')
      localStorage.removeItem('permissions')
      localStorage.removeItem('menus')
      
      // 清除动态路由
      this.dynamicRoutes.forEach(route => {
        if (router.hasRoute(route.name)) {
          router.removeRoute(route.name)
        }
      })
    },
    
    /**
     * 检查权限
     */
    hasPermission(permission) {
      if (!permission) return true
      if (this.permissions.includes('*')) return true
      return this.permissions.includes(permission)
    },
    
    /**
     * 检查角色
     */
    hasRole(role) {
      if (!role) return true
      return this.userInfo.role === role
    },
    
    /**
     * 检查多个权限（满足任一）
     */
    hasAnyPermission(permissions) {
      if (!permissions || permissions.length === 0) return true
      if (this.permissions.includes('*')) return true
      return permissions.some(permission => this.permissions.includes(permission))
    },
    
    /**
     * 检查多个权限（全部满足）
     */
    hasAllPermissions(permissions) {
      if (!permissions || permissions.length === 0) return true
      if (this.permissions.includes('*')) return true
      return permissions.every(permission => this.permissions.includes(permission))
    },
    
    /**
     * 刷新用户信息
     */
    async refreshUserInfo() {
      try {
        const response = await mockGetUserInfo(this.token)
        const userInfo = response.data
        
        this.userInfo = userInfo
        this.permissions = userInfo.permissions
        
        // 更新本地存储
        localStorage.setItem('userInfo', JSON.stringify(userInfo))
        localStorage.setItem('permissions', JSON.stringify(userInfo.permissions))
        
        return userInfo
      } catch (error) {
        console.error('刷新用户信息失败:', error)
        throw error
      }
    }
  }
})